package com.workhours.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.workhours.dto.HolidayResponse;
import com.workhours.entity.Holiday;
import com.workhours.mapper.HolidayMapper;
import com.workhours.vo.HolidayVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 节假日服务类
 * 
 * @author WorkHours
 * @since 2025-09-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class HolidayService {

    private final HolidayMapper holidayMapper;
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    /**
     * 提莫API地址模板
     */
    private static final String TIMOR_API_URL = "http://timor.tech/api/holiday/year/{year}";

    /**
     * 获取指定年份的节假日数据
     * 优先从数据库查询，如果没有则调用API并缓存
     * 
     * @param year 年份
     * @return 节假日列表
     */
    public List<HolidayVO> getHolidaysByYear(Integer year) {
        log.info("获取{}年的节假日数据", year);
        
        // 先从数据库查询
        List<Holiday> holidays = getHolidaysFromDatabase(year);
        
        // 如果数据库中没有数据，则调用API获取并缓存
        if (holidays.isEmpty()) {
            log.info("数据库中没有{}年的节假日数据，开始调用提莫API", year);
            holidays = fetchAndCacheHolidays(year);
        }
        
        // 转换为VO
        return convertToVO(holidays);
    }

    /**
     * 从数据库查询指定年份的节假日
     * 
     * @param year 年份
     * @return 节假日列表
     */
    private List<Holiday> getHolidaysFromDatabase(Integer year) {
        QueryWrapper<Holiday> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year", year);
        queryWrapper.orderByAsc("date");
        return holidayMapper.selectList(queryWrapper);
    }

    /**
     * 调用提莫API获取节假日数据并缓存到数据库
     * 
     * @param year 年份
     * @return 节假日列表
     */
    private List<Holiday> fetchAndCacheHolidays(Integer year) {
        try {
            // 调用提莫API
            log.info("调用提莫API获取{}年节假日数据: {}", year, TIMOR_API_URL.replace("{year}", year.toString()));
            String response = restTemplate.getForObject(TIMOR_API_URL, String.class, year);
            
            if (response == null || response.trim().isEmpty()) {
                log.error("提莫API返回空响应");
                return new ArrayList<>();
            }
            
            log.info("提莫API响应: {}", response);
            
            // 解析响应
            HolidayResponse holidayResponse = objectMapper.readValue(response, HolidayResponse.class);
            
            if (holidayResponse.getCode() != 0) {
                log.error("提莫API返回错误，code: {}", holidayResponse.getCode());
                return new ArrayList<>();
            }
            
            // 转换并保存到数据库
            List<Holiday> holidays = convertAndSaveHolidays(holidayResponse, year);
            log.info("成功缓存{}年的{}条节假日数据", year, holidays.size());
            
            return holidays;
            
        } catch (Exception e) {
            log.error("调用提莫API失败: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 转换API响应数据并保存到数据库
     * 
     * @param response API响应
     * @param year 年份
     * @return 保存的节假日列表
     */
    private List<Holiday> convertAndSaveHolidays(HolidayResponse response, Integer year) {
        List<Holiday> holidays = new ArrayList<>();
        
        if (response.getHoliday() == null) {
            return holidays;
        }
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        
        for (Map.Entry<String, HolidayResponse.HolidayDetail> entry : response.getHoliday().entrySet()) {
            HolidayResponse.HolidayDetail detail = entry.getValue();
            
            Holiday holiday = new Holiday();
            holiday.setDate(LocalDate.parse(detail.getDate(), formatter));
            holiday.setName(detail.getName());
            holiday.setIsHoliday(detail.getHoliday());
            holiday.setYear(year);
            holiday.setCreateTime(LocalDateTime.now());
            
            holidays.add(holiday);
        }
        
        // 批量保存到数据库
        for (Holiday holiday : holidays) {
            try {
                holidayMapper.insert(holiday);
            } catch (Exception e) {
                log.warn("保存节假日数据失败: {}, 错误: {}", holiday.getDate(), e.getMessage());
            }
        }
        
        return holidays;
    }

    /**
     * 转换为VO对象
     * 
     * @param holidays 节假日实体列表
     * @return VO列表
     */
    private List<HolidayVO> convertToVO(List<Holiday> holidays) {
        List<HolidayVO> voList = new ArrayList<>();
        
        for (Holiday holiday : holidays) {
            HolidayVO vo = new HolidayVO();
            vo.setDate(holiday.getDate().toString());
            vo.setName(holiday.getName());
            vo.setIsHoliday(holiday.getIsHoliday());
            voList.add(vo);
        }
        
        return voList;
    }

    /**
     * 刷新指定年份的节假日数据
     * 删除数据库中的旧数据，重新从API获取
     * 
     * @param year 年份
     * @return 刷新后的节假日列表
     */
    public List<HolidayVO> refreshHolidaysByYear(Integer year) {
        log.info("刷新{}年的节假日数据", year);
        
        // 删除数据库中的旧数据
        QueryWrapper<Holiday> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("year", year);
        holidayMapper.delete(deleteWrapper);
        
        // 重新获取数据
        List<Holiday> holidays = fetchAndCacheHolidays(year);
        return convertToVO(holidays);
    }
}
